﻿using System.Text;
 
using System.Data;
using System.Data.Entity;
using System;
using System.Collections.Generic;
using Wedo.Mvc.Utility;
using Wedo.Domain.Models;
using System.Linq;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace Wedo.Recognition.Domain.Models
{
    /// <summary>
    /// 银行的电子交易数据
    /// </summary>
    [DisplayName("银行账单")]
    public class BankData :  Entity
    {
        
        #region 银行上传字段

        /// <summary>
        /// 到账日期
        /// </summary>
        [DisplayName("ReceiveDate")]//, ResourceType = typeof(Wedo.Recognition.Resources.BankData))]
        [System.ComponentModel.DataAnnotations.DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
        [Required(ErrorMessage = "{0} 不能为空！")]

        public DateTime ReceiveDate { set; get; }


        /// <summary>
        /// 银行名称
        /// </summary>
        [DisplayName("BankName")]//, ResourceType = typeof(Wedo.Recognition.Resources.BankData))]
        [Required(ErrorMessage = "{0} 不能为空！")]
        public string BankCode { set; get; }

        /// <summary>
        /// 交易附言2
        /// </summary>
        [DisplayName( "交易附言2")]
        public string TradeAddionalComment { set; get; }

        /// <summary>
        /// 银行备注号码
        /// </summary>
        [DisplayName( "BankRemarkNum")]//, ResourceType = typeof(Wedo.Recognition.Resources.BankData))]
        public string BankRemarkNum { set; get; }

        /// <summary>
        /// 币种
        /// </summary>
        [DisplayName("Currency")]//, ResourceType = typeof(Wedo.Recognition.Resources.BankData))]
        public string Currency { set; get; }

        /// <summary>
        /// 上传日期
        /// </summary>
        [DisplayName( "上传日期")]
        [Required(ErrorMessage = "{0} 不能为空！")]
        public DateTime AccountDate { set; get; }

        /// <summary>
        /// 收款类型分为电汇，汇票，信用证，现金和支票
        /// </summary>
        [DisplayName("ReceiveType")]//, ResourceType = typeof(Wedo.Recognition.Resources.BankData))]
        [Required(ErrorMessage = "{0} 不能为空！")]
        public int ReceiveType { set; get; }

        /// <summary>
        /// 付款人/信用证号/票据号
        /// </summary>
        [DisplayName("Payer")]//, ResourceType = typeof(Wedo.Recognition.Resources.BankData))]
        [Required(ErrorMessage = "{0} 不能为空！")]
        public string Payer { set; get; }

        /// <summary>
        /// 银行实收
        /// </summary>
        [DisplayName("BankPaidIn")]//, ResourceType = typeof(Wedo.Recognition.Resources.BankData))]
        public decimal BankPaidIn { set; get; }

        /// <summary>
        /// 交易附言/LC发票号码
        /// </summary>
        [DisplayName("LCNumber")]//, ResourceType = typeof(Wedo.Recognition.Resources.BankData))]
        public string LCNumber { set; get; }

        /// <summary>
        /// 银行手续费
        /// </summary>
        [DisplayName("BankServiceFee")]//, ResourceType = typeof(Wedo.Recognition.Resources.BankData))]
        [Number]
        public decimal? BankServiceFee { set; get; }

        #endregion

        #region 操作状态
        /// <summary>
        /// 账单数据是否已经导入SAP
        /// </summary>
        [DisplayName( "已导入SAP")]
        public bool ImportSAP { set; get; }


        /// <summary>
        /// 状态 1末锁定 2已锁定
        /// </summary> 
        //3争议 4已处理 5 depending
        [DisplayName("Status")]//, ResourceType = typeof(Wedo.Recognition.Resources.BankData))]
        [Number]
        public int? Status { set; get; }

        /// <summary>
        /// 是否废除
        /// </summary>
        [DisplayName("是否废除")]
        public bool IsDelete { get; set; }
 
        /// <summary>
        /// 是否是Finance签出
        /// </summary>
        [DisplayName( "账务签出")]
        public bool FinanceCheckOut { set; get; }

        /// <summary>
        /// 财务签出人
        /// </summary>
        [DisplayName( "财务签出人")]
        public string FinanceCheckMan { get; set; }


        /// <summary>
        /// 备注
        /// </summary>
        [DisplayName( "备注")]
        public string Remark { set; get; }

        #endregion

        #region 生成付款凭证和转账凭证用字段

        /// <summary>
        ///  账单编号(自动生成)
        /// </summary>
        [DisplayName( "账单编号")]
        public string Assiginment { set; get; }

        /// <summary>
        /// 账单对应的客户编号
        /// </summary>
        [DisplayName( "客户编号")]
        public string CustomerCode { set; get; }

        /// <summary>
        /// 账单对应的客户名称
        /// </summary>
        [DisplayName( "客户名称")]
        public string CustomerName { set; get; }
 
        /// <summary>
        /// 账单是否生成了收款凭证
        /// </summary>
        [DisplayName( "是否生成了收款凭证")]
        public bool GenerateRecieveVoucher { set; get; }

        /// <summary>
        /// 将账单导入SAP的操作人
        /// </summary>
        [DisplayName( "ImportSAPUser")]
        public string ImportSAPUser { set; get; }

        /// <summary>
        /// 账单导入SAP后返回的DocumentNo
        /// </summary>
        [DisplayName( "DocumentNo")]
        public string DocumentNo { set; get; }

        /// <summary>
        /// 账单是否生成了转账凭证
        /// </summary>
        [DisplayName( "是否生成了转账凭证")]
        ////[DataColumn(100, 140)]
        public bool GenerateTransferVoucher { set; get; }

        /// <summary>
        /// 账单生成转账凭证的日期
        /// </summary>
        [DisplayName( "GenerateTransferDate")]
        public DateTime? GenerateTransferDate { set; get; }

        /// <summary>
        /// 账单生成收款凭证的日期
        /// </summary>
        [DisplayName( "GenerateRecieveDate")]
        public DateTime? GenerateRecieveDate { set; get; }


        #endregion

        #region 外键

        public virtual List<CheckRecord> CheckRecord { get; set; }

        public virtual List<PaymentApply> PaymentApply { get; set; }

        public virtual List<RefundmentApply> RefundmentApply { get; set; }

        public virtual List<DisputeApply> DisputeApply { get; set; }

        public virtual List<ReleaseOrder> ReleaseOrder { get; set; }

        #endregion
        
        #region 非数据库字段，业务字段

        /// <summary>
        /// 是否为共享记录
        /// </summary>
        public bool Shared()
        {
            return CheckRecord.Count >1;
        }


        //private static int ErrorRange = int.MinValue;

        ///// <summary>
        /////  有手续费的情况下，认款总额为手续费+实收金额
        /////  无手续费的情况下，实收金额+2000
        ///// </summary>
        //[DisplayName( "可认款总额")]
        //[NotMapped]
        //public decimal TotalAmount
        //{
        //    get
        //    {
        //        if (ErrorRange == int.MinValue)
        //        {
        //            ErrorRange = Wedo.Utility.ConfigData.
        //                GetIntData("ErrorRange").GetValueOrDefault(0);
        //        }

        //        if (BankServiceFee.HasValue && BankServiceFee.Value > 0)
        //            return BankPaidIn + BankServiceFee.Value;
        //        else
        //        return BankPaidIn + ErrorRange;
        //    }
        //}

        /// <summary>
        /// 剩余可认款
        /// </summary>
        /// <returns></returns>
        public decimal Remain()
        {
            if (_Remain == decimal.MinValue)
            {
                _Remain = BankPaidIn - Paymented();
            }
            return _Remain;
        }

        /// <summary>
        /// 剩余可退款
        /// </summary>
        /// <returns></returns>
        public decimal RemainRefundment()
        {
            return BankPaidIn - Refundmented();
        }

        private decimal _Remain=decimal.MinValue;


        private decimal _Paymented = decimal.MinValue;

        /// <summary>
        /// 已确认认款
        /// </summary>
        /// <returns></returns>
        public decimal Paymented()
        {
            if (_Paymented == decimal.MinValue)
            {
                _Paymented = PaymentApply
                     .Where(m => m.Status == 2).Sum(m => m.Amount);
            }
            return _Paymented;
        }

        private decimal _Refundment = decimal.MinValue;

        /// <summary>
        /// 已确认退款
        /// </summary>
        /// <returns></returns>
        public decimal Refundmented()
        {
            if (_Refundment == decimal.MinValue)
            {
                _Refundment = RefundmentApply
                     .Where(m => m.Status == 2).Sum(m => m.Amount);
            }
            return _Refundment;
        }

        /// <summary>
        /// 是否可以财务签出
        /// 财务
        /// </summary>
        /// <returns></returns>
        public bool IsCanFinanceCheck()
        {
            return  IsDelete==false && this.GenerateRecieveVoucher == false && 
                this.FinanceCheckOut == false && 
                ImportSAP == false &&CheckRecord.Count==0;
        }

        /// <summary>
        /// CSR签出
        /// 没有人签出，才能签出
        /// </summary>
        /// <returns></returns>
        public bool IsCanCSRCheck()
        {
            return IsDelete == false && this.CheckRecord.Count == 0;
        }

        /// <summary>
        /// 是否已经签出
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public bool HasChecked(string user)
        {
            if (user.IsNullOrWhiteSpace())
                return false;
            return IsDelete == false && this.CheckRecord.Count(m => m.ApplyMan == user ) > 0;
        }

        /// <summary>
        /// 是否被签出
        /// </summary>
        /// <returns></returns>
        public bool HasChecked()
        {
            return IsDelete == false && this.CheckRecord.Count > 0;
        }

        /// <summary>
        /// 某人的签出记录
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public CheckRecord MyCheck(string user)
        {
            return CheckRecord.FirstOrDefault(m => m.ApplyMan == user);
        }

        /// <summary>
        /// CSR取消本人签出
        /// 本人有签出记录
        /// </summary>
        /// <returns></returns>
        public bool IsCanCancelCSRCheck(string user)
        {
            return HasChecked(user)==true;
        }

        /// <summary>
        /// 是否可认款
        /// CSR已签出还有可认款，没有退款
        /// </summary>
        /// <returns></returns>
        public bool IsCanPayment(string user)
        {
            return Remain() > 0 && HasChecked(user) ;
        }

        /// <summary>
        /// 是否可退款
        /// CSR已签出还有可退款，没有认款
        /// </summary>
        /// <returns></returns>
        public bool IsCanRefundment(string user)
        {
            return  ImportSAP &&RemainRefundment() > 0 && HasChecked(user);
        }

        /// <summary>
        /// 是否能争议
        /// CSR认款有问题或非本人签出
        /// </summary>
        /// <returns></returns>
        public bool IsCanDispute(string user)
        {
            if( IsDelete == false && 
                DisputeApply.Count(m => m.ApplyMan == user && m.Status == 1) == 0)
            {
                if (CheckRecord.Count==0 || (HasChecked(user) && Paymented() == 0))
                    return false;
                else
                    return true;

            }
            return false;
        }

        /// <summary>
        /// 是否可以锁定
        /// 财务角色
        /// </summary>
        /// <returns></returns>
        public bool IsCanLock()
        {
            return IsDelete == false && this.Status == 1 && GenerateRecieveVoucher && this.ImportSAP == false;
        }

        /// <summary>
        /// 是否可以解锁
        /// Complance 角色
        /// </summary>
        /// <returns></returns>
        public bool IsCanCancelLock()
        {
            return IsDelete == false && this.Status == 2;
        }

        /// <summary>
        /// 申请认款用户Code
        /// </summary>
        /// <returns></returns>
        public string PaymentApplyCustomeCode()
        {
            var pay = PaymentApply.OrderBy(m => m.Created).FirstOrDefault();
            if (pay != null)
            {
                return pay.CustomerCode;
            }
            return null;
        }

        /// <summary>
        /// 申请认款用户Name
        /// </summary>
        /// <returns></returns>
        public string PaymentApplyCustomeName()
        {
            var pay = PaymentApply.OrderBy(m => m.Created).FirstOrDefault();
            if (pay != null)
            {
                return pay.CustomerName;
            }
            return null;
        }

        /// <summary>
        /// 已认款订单和金额
        /// </summary>
        /// <returns></returns>
        public string SONO()
        {
            var ps = PaymentApply.Where(m => m.Status == 2).ToList();
            if (ps.Count > 0)
                return string.Join("/", ps.Select(m => m.OrderNum + "(" + m.Amount + ")"));
            else
                return string.Empty;
        }
        #endregion
    }

 
    public class BankDataSearch:CommonTimeSearch
    {
        #region 高级查询
        /// <summary>
        /// 高级查询
        /// </summary>
        public bool AdvancedSearch { get; set; }
 
        /// <summary>
        /// 是否签出,CSR签出
        /// </summary>
        [DisplayName( "CSR签出")]
        public bool? HasChecked { set; get; }

        /// <summary>
        /// 是否财务签出
        /// </summary>
        [DisplayName( "财务签出")]
        public bool? FinanceCheckOut { get; set; }

        /// <summary>
        /// 账单数据是否已经导入SAP
        /// </summary>
        [DisplayName( "导入SAP")]
        public bool? ImportSAP { set; get; }

        /// <summary>
        /// 是否生成了转账凭证
        /// </summary>
        [DisplayName("转账凭证")]
        public bool? TransferVoucher { get; set; }

        /// <summary>
        /// 是否生成了收款凭证
        /// </summary>
        [DisplayName("收款凭证")]
        public bool? RecieveVoucher { get; set; }

        /// <summary>
        /// 状态 1末锁定 2已锁定 
        /// 
        /// </summary>
        // 3争议 4已处理 5 depending，暂时不用
        [DisplayName( "Status")]//, ResourceType = typeof(Wedo.Recognition.Resources.BankData))]
        public int? Status { set; get; }

        /// <summary>
        /// 是否废除
        /// </summary>
        [DisplayName("废除账单")]
        public bool? IsDelete { get; set; }
        #endregion

        /// <summary>
        ///  账单编号
        /// </summary>
        [DisplayName( "账单编号")]
        public string Assiginment { set; get; }

        /// <summary>
        ///  币种
        /// </summary>
        [DisplayName( "币种")]
        public string Currency { get; set; }

    }


    public class BankDataReportSearch : CommonTimeSearch
    {
        /// <summary>
        /// 是否被认款
        /// </summary>
        [DisplayName( "是否被认款")]
        public bool? IsRecognition { get; set; }

        /// <summary>
        /// 是否入账
        /// </summary>
        [DisplayName( "是否入账")]
        public bool? IsInSap { get; set; }

        /// <summary>
        /// 是否有争议
        /// </summary>
        [DisplayName( "是否有争议")]
        public bool? IsDisputed { get; set; }

        /// <summary>
        ///  账单编号
        /// </summary>
        [DisplayName( "账单编号")]
        public string Assiginment { set; get; }

    }
}
